#pragma once
#ifndef H_GUIBASE
#define H_GUIBASE

#include "main.h"
#include "GUI.h"

namespace GUI
{
	class CGUIBase;

	struct GUI_PARAMS{
		Vector2 pos;
		UINT width, height, hotkey, border;
		bool visible, enabled;
		CGUIBase* parent;
	};

	struct GUI_SPRITES{
		CSprite* BG;
		CSprite* Border;
		CSprite* MouseOver;
		CSprite* MouseDown;
		CSprite* g_pCursor;
	};
	struct GUI_COLORS{
		D3DCOLOR BG;
		D3DCOLOR Border;
		D3DCOLOR MouseOver;
		D3DCOLOR MouseDown;
		D3DCOLOR Text;
	};

	void SetGUIColors(GUI_COLORS* _guicolors);
	GUI_COLORS* SetGUIColors();
	GUI_SPRITES* SetGUISprites(CSprite* _bg, CSprite* _border, CSprite* _mouseover, CSprite* _mousedown, CSprite* _cursor);
	GUI_COLORS* SetGUIColors(D3DCOLOR _bg, D3DCOLOR _border, D3DCOLOR _mouseover, D3DCOLOR _mousedown, D3DCOLOR _text);

	class CGUIBase{
	protected:
		RECT m_BoundingBox;
		bool m_bEnabled;
		bool m_bVisible;
		bool m_bMouseOver, m_bButtonDown;
		bool m_bHasFocus, m_bLockFocus, m_bCanFocus;
		UINT m_Type;
		GUI_SPRITES* m_pSprites;
		GUI_COLORS* m_pColors;
		CGUIBase* m_pParent;
		typedef void (*EVENTFUNCTION)(UINT GUIType, UINT Event, CGUIBase* Src, void* Dest);
		EVENTFUNCTION OnGUIEvent;

		Vector2 m_pos, m_drawpos;
		UINT m_width, m_height, m_Hotkey, m_border;
		float m_depth;	  
	public:
		CGUIBase(){
			Init(NULL, NULL, NULL);
		};
		CGUIBase(GUI_PARAMS* params, GUI_COLORS* colors, GUI_SPRITES* sprites){
			Init(params, colors, sprites);
		};
		~CGUIBase(){};

		void Init(GUI_PARAMS* params, GUI_COLORS* colors, GUI_SPRITES* sprites){
			if(params){
				m_pos=params->pos;
				m_width=params->width;
				m_height=params->height;
				m_Hotkey=params->hotkey;
				m_bVisible=params->visible;
				m_bEnabled=params->enabled;
				m_border=params->border;
				m_pParent=params->parent;
				UpdateBB();
			}else{
				m_pos=V0;
				m_width=0;
				m_height=0;
				m_Hotkey=0;
				m_bVisible=false;
				m_bEnabled=false;
				m_border=0;
				m_pParent=NULL;
				UpdateBB();
			}
			m_drawpos=m_pos;
			m_depth=0;

			if(sprites)
				m_pSprites=new GUI_SPRITES(*sprites);
			else
				m_pSprites=NULL;

			if(colors)
				m_pColors=new GUI_COLORS(*colors);
			else
				m_pColors=NULL;
			
			m_bMouseOver=false;
			m_bButtonDown=false;
			m_bHasFocus=false;
			m_bLockFocus=false;
			m_bCanFocus=false;
			OnGUIEvent=NULL;
		}

		virtual bool WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { return false; }
		virtual bool HandleKeyboard( UINT uMsg, WPARAM wParam, LPARAM lParam ) { return false; }
		virtual bool HandleMouse( UINT uMsg, WPARAM wParam, LPARAM lParam ) { return false; }

		void SetEventFunction(EVENTFUNCTION _func){ OnGUIEvent=_func; }
		EVENTFUNCTION GetEventFunction(){ return OnGUIEvent; }

		void UpdateBB(){
			m_drawpos=m_pos;
			CGUIBase* p=m_pParent;
			while(p){
				m_drawpos+=p->GetPos();
				p=p->GetParent();
			}
			m_BoundingBox.left=(long)m_drawpos.x;
			m_BoundingBox.right=(long)m_drawpos.x+m_width;
			m_BoundingBox.top=(long)m_drawpos.y;
			m_BoundingBox.bottom=(long)m_drawpos.y+m_height;
		}
		virtual void Move(Vector2 pos){ 
			m_pos+=pos;
			if(m_pParent){
				m_pos.x=min(max(m_pos.x, 0), m_pParent->GetWidth()-m_width);
				m_pos.y=min(max(m_pos.y, 0), m_pParent->GetHeight()-m_height);
			}
			UpdateBB();
		}
		void Resize(int width, int height){
			m_width=width;
			m_height=height;
			UpdateBB();
		}

		bool GetFocus() { return m_bHasFocus; }
		virtual bool RequestFocus() { return false; }
		virtual bool CanHaveFocus() { return false; }
		virtual void OnFocusIn() { m_bHasFocus = true; }
		virtual void OnFocusOut() { m_bHasFocus = false; }
		virtual void OnMouseEnter() { m_bMouseOver = true; }
		virtual void OnMouseLeave() { m_bMouseOver = false; }
		virtual void OnHotkey() {}

		UINT GetType(){ return m_Type; }
		void SetHotkey( UINT _Hotkey ) { m_Hotkey = _Hotkey; }
		UINT GetHotkey() { return m_Hotkey; }
		void SetVisible( bool _Visible ) { m_bVisible=_Visible; }
		bool GetVisible() { return m_bVisible; }
		void SetEnabled( bool _Enabled ) { m_bEnabled=_Enabled; }
		bool GetEnabled() { return m_bEnabled; }
		void SetFocusLock( bool _locked ) { m_bLockFocus=_locked; }
		bool GetFocusLock() { return m_bLockFocus; }
		void SetDepth(float _depth){m_depth=_depth;}
		float getDepth(){return m_depth;}
		void SetParent(CGUIBase* _parent) { m_pParent=_parent; }
		CGUIBase* GetParent() { return m_pParent; }
		Vector2 GetPos(){ return m_pos; }
		int GetWidth(){ return m_width; }
		int GetHeight(){ return m_height; }

		GUI_SPRITES* GetSprites() { return m_pSprites; }
		void SetSprites( GUI_SPRITES* _gspr ) { m_pSprites=_gspr; }
		GUI_COLORS* GetColors() { return m_pColors; }
		void SetColors( GUI_COLORS* _gcolors ) { m_pColors=_gcolors; }

		bool PtInBB(POINT _pt){ if(PtInRect(&m_BoundingBox, _pt))return true; return false; }
		bool PtInBB(Vector2 _pt){ 
			POINT pt={(long)_pt.x, (long)_pt.y};
			return PtInBB(pt); 
		}
		virtual void Step(){}
		virtual void Draw(){}
	};

}

#endif